Skip to main content

NeoVM 指令集

内置数据类型#

NeoVM 内置的数据类型如下表所示

类型描述
Array数组,实现为一个 List<StackItem>StackItem 是一个抽象类,NeoVM内置的数据类型均继承自StackItem
Boolean布尔类型,实现为一个bool值和两个字节数组TRUEFALSE
Buffer只读字节数组,实现为一个缓存数组byte[]
ByteString只读字节数组,实现为一个ReadOnlyMemory<byte>
Integer整型,实现为一个BigInteger值。
InteropInterface互操作接口
Map实现为一个键值对为StackItem的字典类型Dictionary<PrimitiveType, StackItem>
NullNull类型
Pointer指针类型,实现为一个上下文脚本Script和一个指令位置Position
Struct结构体,继承自Array。结构与Array相同,只是添加了Clone方法和重写了Equals方法。
  • CompoundType :复合类型,包括ArrayMapStruct

  • PrimitiveType :基本类型,包括BooleanByteStringInteger

// boolean 类型private static readonly byte[] TRUE = { 1 };private static readonly byte[] FALSE = { 0 };
private bool value;

指令集#

NeoVM虚拟机一共实现了189个指令,类别如下

常数流程控制栈操作槽操作字符串操作逻辑运算算术运算高级数据结构类型操作
293715506625183

下面将分别介绍各个指令的详细内容。

常数#

常数部分指令主要完成向计算栈中压入常数或者数组的功能。

PUSHINT#

指令PUSHINT8, PUSHINT16, PUSHINT32, PUSHINT64, PUSHINT128, PUSHINT256
字节码0x00, 0x01, 0x02, 0x03, 0x04, 0x05
系统费0.00000001 GAS, 0.00000001 GAS, 0.00000001 GAS, 0.00000001 GAS, 0.00000004 GAS, 0.00000004 GAS
功能向计算栈中压入一个整数,其位长度由本指令后的 8\16\32\64\128\256指定。

PUSHT/PUSHF#

指令PUSHT, PUSHF
字节码0x08, 0x09
系统费0.00000001 GAS
功能向计算栈压入True/False

PUSHA#

指令PUSHA
字节码0x0A
系统费0.00000004 GAS
功能将接下来的四个字节转换为地址,并将该地址压入计算栈。

PUSHNULL#

指令PUSHNULL
字节码0x0B
系统费0.00000001 GAS
功能向计算栈中压入NULL值。

PUSHDATA#

指令PUSHDATA1, PUSHDATA2, PUSHDATA4
字节码0x0C, 0x0D, 0x0E
系统费0.00000008 GAS, 0.00000512 GAS, 0.00004096 GAS
功能向计算栈中压入一个字节数组,其长度由本指令后的 1|2|4 字节指定。

PUSHM1#

指令PUSHM1
字节码0x0F
系统费0.00000001 GAS
功能向计算栈中压入一个整数,其数值等于-1。

PUSHN#

指令PUSH0~PUSH16
字节码0x10~0x20
系统费0.00000001 GAS
功能向计算栈中压入一个整数,其数值等于0~16。

流程控制#

用于控制的虚拟机运行流程,包括跳转、调用等指令。

NOP#

指令NOP
字节码0x21
系统费0.00000001 GAS
功能空操作,但是会使指令计步器加1。

JMP#

指令JMP
字节码0x22
系统费0.00000002 GAS
功能无条件跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMP_L#

指令JMP_L
字节码0x23
系统费0.00000002 GAS
功能无条件跳转到指定偏移位置。偏移量由本指令后的4字节指定。

JMPIF#

指令JMPIF
字节码0x24
系统费0.00000002 GAS
功能当计算栈栈顶元素为true,而不等于0或null时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPIF_L#

指令JMPIF_L
字节码0x25
系统费0.00000002 GAS
功能当计算栈栈顶元素为true,而不等于0或null时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPIFNOT#

指令JMPIFNOT
字节码0x26
系统费0.00000002 GAS
功能当计算栈栈顶元素为false、0或者null时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPIFNOT_L#

指令JMPIFNOT_L
字节码0x27
系统费0.00000002 GAS
功能当计算栈栈顶元素为false、0或者null时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPEQ#

指令JMPEQ
字节码0x28
系统费0.00000002 GAS
功能当栈顶两个元素相等时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPEQ_L#

指令JMPEQ_L
字节码0x29
系统费0.00000002 GAS
功能当栈顶两个元素相等时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPNE#

指令JMPNE
字节码0x2A
系统费0.00000002 GAS
功能当栈顶两个元素不相等时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPNE_L#

指令JMPNE_L
字节码0x2B
系统费0.00000002 GAS
功能当栈顶两个元素不相等时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPGT#

指令JMPGT
字节码0x2C
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素大于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPGT_L#

指令JMPGT_L
字节码0x2D
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素大于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPGE#

指令JMPGE
字节码0x2E
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素大于或者等于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPGE_L#

指令JMPGE_L
字节码0x2F
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素大于或者等于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPLT#

指令JMPLT
字节码0x30
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素小于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPLT_L#

指令JMPLT_L
字节码0x31
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素小于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

JMPLE#

指令JMPLE
字节码0x32
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素小于或者等于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的1字节指定。

JMPLE_L#

指令JMPLE_L
字节码0x33
系统费0.00000002 GAS
功能当计算栈栈顶第一个元素小于或者等于第二个元素时,跳转到指定偏移位置,偏移量由本指令后的4字节指定。

CALL#

指令CALL
字节码0x34
系统费0.00000512 GAS
功能调用指定偏移位置的函数,偏移量由本指令后的1字节指定。

CALL_L#

指令CALL_L
字节码0x35
系统费0.00000512 GAS
功能调用指定偏移位置的函数,偏移量由本指令后的4字节指定。

CALLA#

指令CALLA
字节码0x36
系统费0.00000512 GAS
功能从计算栈栈顶取出函数地址,并调用该函数。

CALLT#

指令CALLT
字节码0x37
系统费0.00032768 GAS
功能从计算栈栈顶取出函数Token,并调用该函数。

ABORT#

指令ABORT
字节码0x38
系统费0 GAS
功能将虚拟机状态立即置为FAULT,且异常不能被捕获。

ASSERT#

指令ASSERT
字节码0x39
系统费0.00000001 GAS
功能从计算栈栈顶取出元素,若该值为False,则退出虚拟机执行,并将虚拟机状态置为FAULT。

THROW#

指令THROW
字节码0x3A
系统费0.00000512 GAS
功能抛出栈顶的异常。

TRY#

指令TRY
字节码0x3B
系统费0.00000004 GAS
功能进入Try语句块,Catch和Finally地址偏移量分别由本指令后的1字节指定。

TRY_L#

指令TRY_L
字节码0x3C
系统费0.00000004 GAS
功能进入Try语句块,Catch和Finally地址偏移量分别由本指令后的4字节指定。

ENDTRY#

指令ENDTRY
字节码0x3D
系统费0.00000004 GAS
功能结束Try块,然后无条件地将控制转移到特定的目标指令,目标地址偏移量由本指令后的1字节指定。

ENDTRY_L#

指令ENDTRY_L
字节码0x3E
系统费0.00000004 GAS
功能结束Try块,然后无条件地将控制转移到特定的目标指令,目标地址偏移量由本指令后的4字节指定。

ENDFINALLY#

指令ENDFINALLY
字节码0x3F
系统费0.00000004 GAS
功能结束Finally块,如果没有异常发生或捕获,则跳转到目标指令ENDTRY/ENDTRY_L,否则将向上层重新抛出异常。

RET#

指令RET
字节码0x40
系统费0 GAS
功能从当前方法中返回。

SYSCALL#

指令SYSCALL
字节码0x41
系统费0 GAS
功能调用互操作服务。

栈操作#

实现对栈的元素做复制、移除、交换等功能。

DEPTH#

指令DEPTH
字节码0x43
系统费0.00000002 GAS
功能将栈元素个数压入计算栈。

DROP#

指令DROP
字节码0x45
系统费0.00000002 GAS
功能移除计算栈栈顶的元素。

NIP#

指令NIP
字节码0x46
系统费0.00000002 GAS
功能移除计算栈栈顶的第二个元素。

XDROP#

指令XDROP
字节码0x48
系统费0.00000016 GAS
功能从计算栈栈顶获取到整数n, 移除计算栈剩余元素中索引为n的元素。

CLEAR#

指令CLEAR
字节码0x49
系统费:0.00000016 GAS
功能清空计算栈。

DUP#

指令DUP
字节码0x4A
系统费0.00000002 GAS
功能复制计算栈栈顶的元素到栈顶。

OVER#

指令OVER
字节码0x4B
系统费0.00000002 GAS
功能复制计算栈的第二个元素到栈顶。

PICK#

指令PICK
字节码0x4D
系统费0.00000002 GAS
功能从计算栈栈顶获取到整数n,并将计算栈剩余元素中索引为n的元素复制到栈顶。

TUCK#

指令TUCK
字节码0x4E
系统费0.00000002 GAS
功能复制计算栈栈顶的元素到计算栈索引为2的位置。

SWAP#

指令SWAP
字节码0x50
系统费0.00000002 GAS
功能交换计算栈栈顶两个元素的位置。

ROT#

指令ROT
字节码0x51
系统费0.00000002 GAS
功能移动计算栈索引为2的元素到栈顶。

ROLL#

指令ROLL
字节码0x52
系统费0.00000016 GAS
功能从计算栈栈顶获取到整数n,并将计算栈剩余元素中索引为n的元素移动到栈顶。

REVERSE3#

指令REVERSE3
字节码0x53
系统费0.00000002 GAS
功能反转计算栈栈顶前三个元素的顺序。

REVERSE4#

指令REVERSE4
字节码0x54
系统费0.00000002 GAS
功能反转计算栈栈顶前四个元素的顺序。

REVERSEN#

指令REVERSEN
字节码0x55
系统费0.00000016 GAS
功能从计算栈栈顶获取到整数n,并反转计算栈剩余元素中前n个元素的顺序。

槽操作#

INITSSLOT#

指令INITSSLOT
字节码0x56
系统费0.00000016 GAS
功能初始化当前执行上下文的静态字段列表。

INITSLOT#

指令INITSLOT
字节码0x57
系统费0.00000064 GAS
功能初始化当前执行上下文的参数槽和局部变量列表。

LDSFLDN#

指令LDSFLD0~LDSFLD6
字节码0x58~0x5E
系统费0.00000002 GAS
功能将指定索引处的静态字段压入计算栈,索引值为0~6。

LDSFLD#

指令LDSFLD
字节码0x5F
系统费0.00000002 GAS
功能将指定索引处的静态字段压入计算栈。索引表示为1字节的无符号整数。

STSFLDN#

指令STSFLD0~STSFLD6
字节码0x60~0x0x66
系统费0.00000002 GAS
功能将计算栈栈顶元素存入静态列表的指定索引处,索引值为0~6。

STSFLD#

指令STSFLD
字节码0x67
系统费0.00000002 GAS
功能将计算栈栈顶元素存入静态列表的指定索引处。索引表示为1字节的无符号整数。

LDLOCN#

指令LDLOC0~LDLOC6
字节码0x68~0x6E
系统费0.00000002 GAS
功能将指定索引处的局部变量压入计算栈,索引值为0~6。

LDLOC#

指令LDLOC
字节码0x6F
系统费0.00000002 GAS
功能将指定索引处的局部变量压入计算栈。索引表示为1字节的无符号整数。

STLOCN#

指令STLOC0~STLOC6
字节码0x70~0x76
系统费0.00000002 GAS
功能将计算栈栈顶元素存入局部变量表的指定索引处,索引值为0~6。

STLOC#

指令STLOC
字节码0x77
系统费0.00000002 GAS
功能将计算栈栈顶元素存入局部变量表的指定索引处。索引表示为1字节的无符号整数。

LDARGN#

指令LDARG0~LDARG6
字节码0x78~0x7E
系统费0.00000002 GAS
功能将指定索引处的参数压入计算栈,索引值为0~6。

LDARG#

指令LDARG
字节码0x7F
系统费0.00000002 GAS
功能将指定索引处的参数压入计算栈。索引表示为1字节的无符号整数。

STARGN#

指令STARG0~STARG6
字节码0x80~0x86
系统费0.00000002 GAS
功能将计算栈栈顶元素存入参数槽的指定索引处,索引值为0~6。

STARG#

指令STARG
字节码0x87
系统费0.00000002 GAS
功能将计算栈栈顶元素存入参数槽的指定索引处。索引表示为1字节的无符号整数。

字符串操作#

NEWBUFFER#

指令NEWBUFFER
字节码0x88
系统费0.00000256 GAS
功能创建缓冲区

MEMCPY#

指令MEMCPY
字节码0x89
系统费0.00002048 GAS
功能内存复制

CAT#

指令CAT
字节码0x8B
系统费0.00002048 GAS
功能拼接两个字符串

SUBSTR#

指令SUBSTR
字节码0x8C
系统费0.00002048 GAS
功能获取子字符串。

LEFT#

指令LEFT
字节码0x8D
系统费0.00002048 GAS
功能获取字符串中指定位置左边的字符串。

RIGHT#

指令RIGHT
字节码0x8E
系统费0.00002048 GAS
功能获取字符串中指定位置右边的字符串。

逻辑运算#

INVERT#

指令INVERT
字节码0x90
系统费0.00000004 GAS
功能对计算栈栈顶的元素按位取反。

AND#

指令AND
字节码0x91
系统费0.00000008 GAS
功能对计算栈栈顶的两个元素执行按位与运算。

OR#

指令OR
字节码0x92
系统费0.00000008 GAS
功能对计算栈栈顶的两个元素执行按位或运算。

XOR#

指令XOR
字节码0x93
系统费0.00000008 GAS
功能对计算栈栈顶的两个元素执行按位异或运算。

EQUAL#

指令EQUAL
字节码0x97
系统费0.00000032 GAS
功能判断计算栈栈顶的两个元素是否相等。若相等,则返回1,否则返回0。

NOTEQUAL#

指令NOTEQUAL
字节码0x98
系统费0.00000032 GAS
功能判断计算栈栈顶的两个元素是否不相等。若不相等,则返回1,否则返回0。

算术运算#

SIGN#

指令SIGN
字节码0x99
系统费0.00000004 GAS
功能获取计算栈栈顶的BigInteger的符号(负、正或零)。

ABS#

指令ABS
字节码0x9A
系统费0.00000004 GAS
功能求计算栈栈顶的BigInteger的绝对值。

NEGATE#

指令NEGATE
字节码0x9B
系统费0.00000004 GAS
功能求计算栈栈顶的BigInteger的相反数。

INC#

指令INC
字节码0x9C
系统费0.00000004 GAS
功能将计算栈栈顶的BigInteger加1。

DEC#

指令DEC
字节码0x9D
系统费0.00000004 GAS
功能将计算栈栈顶的BigInteger减1。

ADD#

指令ADD
字节码0x9E
系统费0.00000008 GAS
功能对计算栈栈顶的两个BigInteger执行加法运算。

SUB#

指令SUB
字节码0x9F
系统费0.00000008 GAS
功能用计算栈第二个BigInteger减去第一个BigInteger。

MUL#

指令MUL
字节码0xA0
系统费0.00000008 GAS
功能对计算栈栈顶的两个BigInteger执行乘法运算。

DIV#

指令DIV
字节码0xA1
系统费0.00000008 GAS
功能用计算栈第二个BigInteger除以第一个BigInteger。

MOD#

指令MOD
字节码0xA2
系统费0.00000008 GAS
功能用计算栈第二个BigInteger除以第一个BigInteger取余。

POW#

指令POW
字节码0xA3
系统费0.00000064 GAS
功能用计算栈第二个BigInteger为底数,第一个integer为指数,求乘方。

SQRT#

指令SQRT
字节码0xA4
系统费0.00000064 GAS
功能求计算栈第一个非负BigInteger的开方,并向下取整为BigInteger。

SHL#

指令SHL
字节码0xA8
系统费0.00000008 GAS
功能从计算栈栈顶获取到整数n,并对剩余计算栈栈顶的BigInteger执行左移n位运算。

SHR#

指令SHR
字节码0xA9
系统费0.00000008 GAS
功能从计算栈栈顶获取到整数n,并对剩余计算栈栈顶的BigInteger执行右移n位运算。

NOT#

指令NOT
字节码0xAA
系统费0.00000004 GAS
功能对计算栈栈顶的元素执行逻辑非运算。

BOOLAND#

指令BOOLAND
字节码0xAB
系统费0.00000008 GAS
功能对计算栈栈顶的两个元素执行逻辑与运算。

BOOLOR#

指令BOOLOR
字节码0xAC
系统费0.00000008 GAS
功能对计算栈栈顶的两个元素执行逻辑或运算。

NZ#

指令NZ
字节码0xB1
系统费0.00000004 GAS
功能判断计算栈栈顶的BigInteger是否为非0值。

NUMEQUAL#

指令NUMEQUAL
字节码0xB3
系统费0.00000008 GAS
功能判断计算栈栈顶的两个BigInteger是否相等。

NUMNOTEQUAL#

指令NUMNOTEQUAL
字节码0xB4
系统费0.00000008 GAS
功能判断计算栈栈顶的两个BigInteger是否不相等。

LT#

指令LT
字节码0xB5
系统费0.00000008 GAS
功能判断计算栈第二个BigInteger是否小于第一个BigInteger。

LE#

指令LE
字节码0xB6
系统费0.00000008 GAS
功能判断计算栈第二个BigInteger是否小于等于第一个BigInteger。

GT#

指令GT
字节码0xB7
系统费0.00000008 GAS
功能判断计算栈第二个BigInteger是否大于第一个BigInteger。

GE#

指令GE
字节码0xB8
系统费0.00000008 GAS
功能判断计算栈第二个BigInteger是否大于等于第一个BigInteger。

MIN#

指令MIN
字节码0xB9
系统费0.00000008 GAS
功能获取计算栈栈顶的两个BigInteger中的最小值。

MAX#

指令MAX
字节码0xBA
系统费0.00000008 GAS
功能获取计算栈栈顶的两个BigInteger中的最大值。

WITHIN#

指令WITHIN
字节码0xBB
系统费0.00000008 GAS
功能判断计算栈中的第三个BigInteger是否大于等于第二个BigInteger且小于第一个BigInteger。

高级数据结构#

实现对Array、Map、Struct等的常用操作。

PACKMAP#

指令PACKMAP
字节码0xBE
系统费0.00002048 GAS
功能将计算栈栈顶的2n个元素打包成Map。第1个为key,第2个为第1个的value。

PACKSTRUCT#

指令PACKSTRUCT
字节码0xBF
系统费0.00002048 GAS
功能将计算栈栈顶的n个元素打包成结构体。

PACK#

指令PACK
字节码0xC0
系统费0.00002048 GAS
功能将计算栈栈顶的n个元素打包成数组。

UNPACK#

指令UNPACK
字节码0xC1
系统费0.00002048 GAS
功能将计算栈栈顶的数组拆包成元素序列。

NEWARRAY0#

指令NEWARRAY0
字节码0xC2
系统费0.00000016 GAS
功能向计算栈栈顶压入一个空数组。

NEWARRAY#

指令NEWARRAY
字节码0xC3
系统费0.00000512 GAS
功能向计算栈栈顶压入一个大小为n的数组。

NEWARRAY_T#

指令NEWARRAY_T
字节码0xC4
系统费0.00000512 GAS
功能向计算栈栈顶压入一个元素类型为T且大小为n的数组。

NEWSTRUCT0#

指令NEWSTRUCT0
字节码0xC5
系统费0.00000016 GAS
功能向计算栈栈顶压入一个空的结构体。

NEWSTRUCT#

指令NEWSTRUCT
字节码0xC6
系统费0.00000512 GAS
功能向计算栈栈顶压入一个元素全为0且大小为n的结构体。

NEWMAP#

指令NEWMAP
字节码0xC8
系统费0.00000008 GAS
功能向计算栈栈顶压入一个空的Map。

SIZE#

指令SIZE
字节码0xCA
系统费0.00000004 GAS
功能获取计算栈栈顶元素的大小。

HASKEY#

指令HASKEY
字节码0xCB
系统费0.00000064 GAS
功能从计算栈栈顶获取索引n(或键)和数组(Map,Buffer,ByteString)。若n在数组(Map,Buffer,ByteString)的长度范围内,则向栈顶压入True,否则压入False。

KEYS#

指令KEYS
字节码0xCC
系统费0.00000016 GAS
功能获取计算栈栈顶的Map的所有Key,以所有Key构造新的Array并压入栈顶。

VALUES#

指令VALUES
字节码0xCD
系统费0.00008192 GAS
功能获取计算栈栈顶的元素(Array或Map)的所有Value,以所有Value构造新的Array并压入栈顶.

PICKITEM#

指令PICKITEM
字节码0xCE
系统费0.00000064 GAS
功能获取计算栈栈顶的数组中的第n个元素。

APPEND#

指令APPEND
字节码0xCF
系统费0.00008192 GAS
功能向计算栈栈顶的Array中添加一个新项。

SETITEM#

指令SETITEM
字节码0xD0
系统费0.00008192 GAS
功能对计算栈栈顶的元素(Array,Map或Buffer)中的指定索引(或key)元素赋值。

REVERSEITEMS#

指令REVERSEITEMS
字节码0xD1
系统费0.00008192 GAS
功能反转计算栈栈顶Array或Buffer中的元素。

REMOVE#

指令REMOVE
字节码0xD2
系统费0.00000016 GAS
功能从Array或Map中移除指定索引(或key)元素。

CLEARITEMS#

指令CLEARITEMS
字节码0xD3
系统费0.00000016 GAS
功能清空计算栈栈顶CompoundType类型元素中的所有元素。

POPITEM#

指令POPITEM
字节码0xD4
系统费0.00000016 GAS
功能弹出栈顶Array数组最后的元素,并压入计算栈栈顶。

类型操作#

ISNULL#

指令ISNULL
字节码0xD8
系统费0.00000002 GAS
功能判断计算栈栈顶元素是否为null

ISTYPE#

指令ISTYPE
字节码0xD9
系统费0.00000002 GAS
功能判断计算栈栈顶元素是否为指定的元素类型。

CONVERT#

指令CONVERT
字节码0xDB
系统费0.00002048 GAS
功能将计算栈栈顶元素转化为指定的元素类型。